package rt2

import (
	"fmt"
	"net"
	"sync"

	"github.com/sirupsen/logrus"
)

type UdpRecvDecoder struct {
	Conn     *net.UDPConn
	Dec      *Decoder
	stopChan chan struct{}
	running  bool

	frameChan chan *Frame

	mu sync.Mutex
}

func NewRecvDecoder(conn *net.UDPConn, dec *Decoder) *UdpRecvDecoder {
	return &UdpRecvDecoder{
		Conn: conn,
		Dec:  dec,
	}
}

func (u *UdpRecvDecoder) Stop() {
	u.mu.Lock()
	defer u.mu.Unlock()
	if u.running {
		u.stopChan <- struct{}{}
		close(u.stopChan)
		close(u.frameChan)

		u.running = false
	}
}
func (u *UdpRecvDecoder) WaitStop() {
	if u.running {
		<-u.stopChan
	}
}
func (u *UdpRecvDecoder) Start(addr string) <-chan *Frame {
	if u.running {
		return u.frameChan
	}

	u.mu.Lock()
	defer u.mu.Unlock()

	u.stopChan = make(chan struct{})
	u.frameChan = make(chan *Frame, 10)

	// 创建一个缓冲区用于接收消息
	buffer := make([]byte, 1024)
	u.running = true
	go func() {
		for {
			// 检查是否收到停止信号
			select {
			case <-u.stopChan:
				// 当协程退出时，关闭组播连接
				if u.Conn != nil {
					u.Conn.Close()
				}
				u.running = false
				close(u.stopChan)
				close(u.frameChan)
				return
			default:
				// 接收组播消息
				n, remoteAddr, err := u.Conn.ReadFromUDP(buffer)
				if err != nil {
					fmt.Printf("Error reading from multicast: %v\n", err)
					return
				}
				if addr != "" && addr != remoteAddr.String() {
					logrus.Errorf("接收到非指定地址的数据，忽略！指定地址: %s, 发送源: %s", addr, remoteAddr.String())
					return
				}
				fs := u.Dec.RecvAndDecode(buffer[:n])
				for _, f := range fs {
					u.frameChan <- f
				}
			}
		}
	}()
	return u.frameChan
}
